#pragma once


/*************************************************
                    头文件
**************************************************/
// 通用库
#include <vector>
#include <filesystem>
#include <regex>
#include <cctype>
#include <functional>
#include <algorithm>


// 项目内部
#include "xlnt.hpp"



/*************************************************
                    宏定义
**************************************************/
namespace fs = std::filesystem;



/*************************************************
                    代码块
**************************************************/
namespace XlsxProcessor {


typedef struct _data_ {
    std::string id;
    std::string description;
    std::string safety;
    std::string type;
}DATA_STRUCT;


class Processer {
public:
    // 显式定义默认构造函数
    Processer() = default;
    virtual ~Processer() = default; // 建议添加虚析构函数

    // 纯虚函数
    virtual void loadSheet(const std::string& sheetName) = 0;

    void load(const std::string& filePath) {
        fs::path fPath(filePath);
        m_wb.load(fPath.wstring());
        m_ws = m_wb.active_sheet();
    }


    
    
    
    xlnt::row_t getRowsCount() const {
        return m_ws.rows().length();
    }

    void save(const std::string& filePath) {
        fs::path fPath(filePath);
        m_wb.save(fPath.wstring());
    }

protected:
    xlnt::workbook m_wb;
    xlnt::worksheet m_ws;
};



class Reader : public Processer{
public:
    // 显式定义默认构造函数
    Reader() = default;
    virtual ~Reader() = default; // 建议添加虚析构函数

    void loadSheet(const std::string& sheetName) override {
        m_ws = m_wb.sheet_by_title(sheetName);
    }

    std::vector<DATA_STRUCT> readLine(
        const int& row,
        const int& id_col,
        const int& description_col,
        const int& safety_col,
        const int& type_col) {
        std::vector<DATA_STRUCT> res;

        std::vector<std::string> id_vec = readFromCell(row, id_col, R"(\[((\w+\d*[-_]+)+\d+)\])");
        std::vector<std::string> des_vec = readFromCell(row, description_col, R"(\[.*\]\s*([^\[\]]+)$)");
        std::string safety = m_ws.cell(xlnt::cell_reference(safety_col, row)).to_string();
        std::string type = m_ws.cell(xlnt::cell_reference(type_col, row)).to_string();
    
        int index = 0;
        for(auto const& id: std::as_const(id_vec)) {
            DATA_STRUCT data;
            data.id = id;
            data.description = des_vec[index++];
            data.safety = safety;
            data.type = type;
            
            res.push_back(data);
        }

        return res;
    }

    

private:
    std::vector<std::string> getStrVectorByRegexStr(const std::string& str, const std::string& pattern_str) {
        std::vector<std::string> res;
        std::regex pattern(pattern_str);
        std::smatch match;

        // 使用迭代器遍历所有匹配
        auto words_begin = std::sregex_iterator(str.begin(), str.end(), pattern);
        auto words_end = std::sregex_iterator();

        // 遍历匹配
        for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
            std::smatch match = *i;
            if (match.size() > 1) {
                // match[1] 是捕获组 1 的内容
                res.push_back(match[1].str());
            }
        }

        return res;
    }

    std::vector<std::string> readFromCell(const int& row, const int& col, const std::string& regex_str) {
        auto cell_value = m_ws.cell(xlnt::cell_reference(col, row));
        return getStrVectorByRegexStr(cell_value.to_string(), regex_str);
    }
    

};




class writer  : public Processer {
public:
    // 显式定义默认构造函数
    writer() = default;
    virtual ~writer() = default; // 建议添加虚析构函数

    void loadSheet(const std::string& sheetName) override {
        std::vector<std::string> titles = m_wb.sheet_titles();

        std::function<std::string(std::string)> to_upper = [](std::string str) {
            std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::toupper(c); });
            return str;
        };

        bool flag = false;
        int index = 0;
        for(auto title : titles) {
            if (to_upper(title) == to_upper(sheetName)) {
                flag = true;
                break;
            } else {
                index++;
            }
        }

        if (flag) {
            m_ws = m_wb.sheet_by_index(index);
        } else {  
            m_ws = m_wb.create_sheet();
            m_ws = m_wb.sheet_by_index(m_wb.sheet_count() - 1);
        }
        m_ws.title(sheetName);
    }

    void setColumnWidth(const int& col, const double& width) {
        m_ws.column_properties(col).width = width;
    }


    void writeString(const int& row, const int& col, const std::string& str) {
        // 创建格式并启用自动换行
        xlnt::format fmt = m_wb.create_format();
        fmt.alignment(xlnt::alignment().wrap(true));
        m_ws.cell(xlnt::cell_reference(col, row)).format(fmt);
        m_ws.cell(xlnt::cell_reference(col, row)).value(str);
    }
};





}